home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 21 / Mac Magazin and MacEasy Magazine CD - Issue 21.iso / Wissenschaft & Technik / yorick12vr1-nofpu folder / include / color.i < prev    next >
Text File  |  1995-12-12  |  4KB  |  145 lines

  1. /*
  2.    COLOR.I
  3.    Hue-Saturation-Value color representation routines and other
  4.    color and palette construction tools.
  5.  
  6.    $Id$
  7.  */
  8.  
  9. local palette_directory;
  10. /* DOCUMENT palette_directory= "~/Gist/"
  11.      holds the default directory for the dump_palette command.
  12.      The directory name *must* end with "/"; the default is shown.
  13.    SEE ALSO: dump_palette
  14.  */
  15. palette_directory= "~/Gist/";
  16.  
  17. func dump_palette(name)
  18. /* DOCUMENT dump_palette, name
  19.      dump the current palette under the NAME.  If NAME contains no
  20.      slash characters, the palette_directory will be prepended to the
  21.      name.  The name can be fed back to the palette command in order
  22.      to reload the cumped palette.
  23.    SEE ALSO: brighten, palette, palette_directory
  24.  */
  25. {
  26.   if (!strmatch(name,"/")) name= palette_directory+name;
  27.   local r, g, b;
  28.   palette, query=1, r, g, b;
  29.   f= create(name);
  30.   write,f, format="%s\n", "ncolors= "+pr1(numberof(r));
  31.   write,f, format="%s\n", "ntsc= 1";
  32.   write,f, format="%s\n", "#  r   g   b";
  33.   write,f, format="%4d%4d%4d\n", r, g, b;
  34. }
  35.  
  36. func brighten(factor)
  37. /* DOCUMENT brighten, factor
  38.          or brighten
  39.      brighten the current palette by the specified FACTOR.
  40.      The FACTOR is the slope of the transfer function for the color value
  41.      (see to_hsv for a description of the hsv color system); a value of
  42.      1.0 always remains 1.0, but values near 0.0 change by FACTOR.
  43.      FACTOR= 1.0 is a no-op.  The default factor is 4.0.
  44.    SEE ALSO: dump_palette
  45.  */
  46. {
  47.   if (is_void(factor)) factor= 4.0;
  48.   local r, g, b;
  49.   palette, query=1, r, g, b;
  50.   hsv= to_hsv([r,g,b]);
  51.   v= hsv(,3);
  52.   /* this function is a symmetric parabolic mapping from [0,1] to [0,1] */
  53.   fv= 0.5*(factor-1.0)*v;
  54.   n= (2.*factor-fv)*v;
  55.   d= 1.+fv+sqrt(max(1.+(factor^2-1.)*v,0.));
  56.   hsv(,3)= n/d;
  57.   /* here is an alternative which has the property that applying the
  58.      function twice is the same as applying with the product of the
  59.      two factors - however, this nice property is spoiled by the
  60.      quantization of the byte scaling of the rgb values */
  61.   /* hsv(,3)= 1.-(1.-v)^factor; */
  62.   rgb= to_rgb(hsv);
  63.   palette, rgb(,1),rgb(,2),rgb(,3);
  64. }
  65.  
  66. func to_rgb(hsv)
  67. /* DOCUMENT rgb= to_rgb(hsv)
  68.          or rgb= to_rgb([h,s,v])
  69.      return the RGB representation of the n-by-3 array of HSV colors
  70.      rgb: red, green, blue from 0 to 255
  71.      hsv: h= hue in degrees, red=0, green=120, blue=240
  72.           s= saturation from 0 (gray) to 1 (full hue)
  73.           v= value from 0 (black) to 1 (full intensity)
  74.       s= 1 - min(r,g,b)/max(r,g,b)
  75.           v= max(r,g,b)/255
  76.    SEE ALSO: to_hsv
  77.  */
  78. {
  79.   hsv= double(hsv);
  80.   h= hsv(*,1);
  81.   s= hsv(*,2);
  82.   v= hsv(*,3);
  83.  
  84.   /* normalize hue to lie in 0<=h<360 */
  85.   h= h % 360.0;
  86.   h+= (h<0.0)*360.0;
  87.  
  88.   /* divide hue into 60 degree sectors */
  89.   i= long(h/60.0);
  90.   f= h/60.0 - i;
  91.  
  92.   p= 1.0 - s;
  93.   q= 1.0 - s*f;
  94.   t= 1.0 - s*(1.-f);
  95.   /* each hue sector will be represented by rgb values taken
  96.    * from one of v, p, q, or t */
  97.   r= ((i==0|i==5) + (i==2|i==3)*p + (i==1)*q + (i==4)*t) * v;
  98.   g= ((i==1|i==2) + (i==4|i==5)*p + (i==3)*q + (i==0)*t) * v;
  99.   b= ((i==3|i==4) + (i==0|i==1)*p + (i==5)*q + (i==2)*t) * v;
  100.  
  101.   /* return array same shape as input */
  102.   rgb= hsv;
  103.   rgb(*,1)= r;
  104.   rgb(*,2)= g;
  105.   rgb(*,3)= b;
  106.   return bytscl(rgb,top=255,cmin=0.0,cmax=1.0);
  107. }
  108.  
  109. func to_hsv(rgb)
  110. /* DOCUMENT hsv= to_hsv(rgb)
  111.          or hsv= to_hsv([r,g,b])
  112.      return the HSV representation of the n-by-3 array of RGB colors
  113.      rgb: red, green, blue from 0 to 255
  114.      hsv: h= hue in degrees, red=0, green=120, blue=240
  115.           s= saturation from 0 (gray) to 1 (full hue)
  116.           v= value from 0 (black) to 1 (full intensity)
  117.       s= 1 - min(r,g,b)/max(r,g,b)
  118.           v= max(r,g,b)
  119.    SEE ALSO: to_rgb
  120.  */
  121. {
  122.   rgb/= 255.0;
  123.   hsv= rgb;
  124.   rgb= rgb(*,);
  125.   r= rgb(,1);
  126.   g= rgb(,2);
  127.   b= rgb(,3);
  128.  
  129.   /* compute and normalize hue angle */
  130.   h= atan((g-b)*sqrt(0.75), r-0.5*(g+b)+1.e-30)/pi * 180.;
  131.   h+= (h<0.0)*360.;
  132.  
  133.   /* any given hue is adjacent to one primary, opposite a second primary,
  134.    * and neutral for the third
  135.    * value is adjacent, which is always maximum
  136.    * the ratio of opposite to adjacent is 1-saturation */
  137.   v= max(r,g,b);
  138.   s= 1.0 - (min(r,g,b)+1.e-30)/(v+1.e-30);
  139.  
  140.   hsv(*,1)= h;
  141.   hsv(*,2)= s;
  142.   hsv(*,3)= v;
  143.   return hsv;
  144. }
  145.